package net.siufung.boot.datasource.enums;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import net.siufung.boot.datasource.keywords.MySql5KeyWordsHandler;
import net.siufung.boot.datasource.querys.MySql5Query;
import net.siufung.boot.datasource.querys.MySql8Query;
import net.siufung.boot.datasource.rules.IDbKeyWordsHandler;
import net.siufung.boot.datasource.rules.IDbQuery;
import net.siufung.boot.datasource.rules.IDbType;
import net.siufung.core.model.EnumsVo;
import net.siufung.core.model.IEnum;
import net.siufung.core.utils.select.BranchBuilder;
import net.siufung.core.utils.select.Selector;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 陈建峰
 * @since 2022/8/11 5:38 下午
 */
@AllArgsConstructor
public enum DbTypes implements IDbType {

    /**
     * MySql5数据库
     */
    MYSQL_5("mysql_5", "MySql5数据库", MySql5Query.INSTANCE, MySql5KeyWordsHandler.INSTANCE),

    /**
     * MySql8数据库
     */
    MYSQL_8("mysql_8", "MySql8数据库", MySql8Query.INSTANCE, null),

    /**
     * H2数据库
     */
    H2("h2", "H2数据库", null , null),

    /**
     * Postgre数据库
     */
    POSTGRE_SQL("postgresql", "Postgre数据库", null , null),

    /**
     * Oracle 数据库
     */
    ORACLE("oracle", "Oracle11g及以下数据库(高版本推荐使用ORACLE_NEW)", null , null),

    /**
     * ORACLE_12C
     */
    ORACLE_12C("oracle12c", "Oracle12c+数据库", null , null);

    @Getter
    @Setter
    private String value;

    @Getter
    @Setter
    private String desc;

    @Getter
    @Setter
    private IDbQuery dbQuery;

    @Getter
    @Setter
    private IDbKeyWordsHandler dbKeyWordsHandler;

    public static DbTypes get(String value) {
        return IEnum.get(DbTypes.class,
                enums -> enums.getValue().equals(value));
    }

    public static String getDesc(String value) {
        return IEnum.getDesc(DbTypes.class,
                enums -> enums.getValue().equals(value));
    }

    public static List<EnumsVo> getList(){
        return IEnum.findList(DbTypes.class).stream()
                .map(element -> new EnumsVo(element.getValue(), element.getDesc()))
                .collect(Collectors.toList());
    }

    @Override
    public IDbQuery getDbQueryByType() {
        return DbQuerySelectors.use(this)
                .test(DbQuerySelectors.equals(dbQuery).then(dbQuery))
                .or(MySql5Query.INSTANCE);
    }

    @Override
    public IDbKeyWordsHandler getDbKeyWordsHandlerByType() {
        return DbKeyWordsHandlerSelectors.use(this)
                .test(DbKeyWordsHandlerSelectors.equals(dbKeyWordsHandler).then(dbKeyWordsHandler))
                .or(MySql5KeyWordsHandler.INSTANCE);
    }

    static class DbQuerySelectors {

        /**
         * 使用指定参数构建一个选择器
         * @param dbType 参数
         * @return 返回选择器
         */
        static Selector<IDbType, IDbQuery> use(IDbType dbType) {
            return new Selector<>(dbType);
        }

        /**
         * 这个分支构建器用于构建用于支持
         * @param dbQuery 分支的值
         * @return 返回分支构建器
         */
        static BranchBuilder<IDbType, IDbQuery> equals(IDbQuery dbQuery) {
            return BranchBuilder.of(dbType ->
                    StrUtil.equals(dbType.getValue(), dbQuery.getDbType().getValue()));
        }
    }

    static class DbKeyWordsHandlerSelectors {
        /**
         * 使用指定参数构建一个选择器
         * @param dbType 参数
         * @return 返回选择器
         */
        static Selector<IDbType, IDbKeyWordsHandler> use(IDbType dbType) {
            return new Selector<>(dbType);
        }

        /**
         * 这个分支构建器用于构建用于支持
         * @param dbKeyWordsHandler 分支的值
         * @return 返回分支构建器
         */
        static BranchBuilder<IDbType, IDbKeyWordsHandler> equals(IDbKeyWordsHandler dbKeyWordsHandler) {
            return BranchBuilder.of(dbType ->
                    StrUtil.equals(dbType.getValue(), dbKeyWordsHandler.getDbType().getValue()));
        }

    }
}
